//
//  Audio.swift
//  GhostWorld
//
//  Created by Kam on 2018/4/5.
//  Copyright © 2018 LKGood. All rights reserved.
//

import Foundation
import CoreData

private let entityName = CoreDataEntityName.audio.rawValue
private let context = CoreDataHelper.getContext()
private let progressEntityName = CoreDataEntityName.audioPlayProgress.rawValue

enum AudioSortType: Int {
  case ascending = 0
  case descending = 1
}

extension Audio {
  var album: Album? {
    get {
      let id = Int(albumID)
      return EntityManager.fetch(Album.self, fetchType: .id(id))?.first
    }
  }
  
  var localURL: URL? {
    get {
      if let cacheName = self.cacheFileName,
        let cachePath = LocalFileManager.shared.cacheRootPath {
        
        let localPath = "\(cachePath)/\(cacheName)"
        if FileManager.default.fileExists(atPath: localPath) {
          return URL(fileURLWithPath: localPath)
        } else {
          return nil
        }
      } else {
        return nil
      }
    }
  }
  
  var cacheFileName: String? {
    get {
      if let album = self.album,
        let audioURLString = url,
        let url = URL(string: audioURLString) {
        
        let lastPathComponent = url.lastPathComponent
        var fileExtension = ""
        if let index = lastPathComponent.index(of: ".") {
          fileExtension = lastPathComponent.substring(from: index + 1)
        }
        var userIdentifier = -1
        if let currentUser = UserManager.shared.currentUser {
          userIdentifier = currentUser.identifier
        }
        let fileName = "ca_\(userIdentifier)_\(album.id)_\(self.id)\(fileExtension.count > 0 ? ".\(fileExtension)" : ".mp3")"
        return fileName
      } else {
        return nil
      }
    }
  }
  
  var cacheFileSizeInMegaBytes: Float {
    get {
      if let url = localURL {
        let filePath = url.path
        var fileSize: Float
        do {
          //return [FileAttributeKey : Any]
          let attr = try FileManager.default.attributesOfItem(atPath: filePath)
          if let size = attr[FileAttributeKey.size] {
            fileSize = (size as! NSNumber).floatValue
            
            return fileSize / 1000 / 1000
          } else {
            return 0
          }
        } catch let error {
          loggingPrint("Get auido cache file size error. \(error.localizedDescription)")
        }
      }
      return 0
    }
  }
}

extension Audio {
  func savePlayProgress(_ progress: Float) {
    var theProgress = progress
    if theProgress >= 1 {
      theProgress = 1
    }
    
    let request = NSFetchRequest<AudioPlayProgress>()
    request.entity = NSEntityDescription.entity(forEntityName: progressEntityName, in: context)
    request.predicate = NSPredicate(format: "audioID = %@", "\(id)")
    do {
      let audioPlayProgress = try context.fetch(request).first
      
      if audioPlayProgress != nil {
        audioPlayProgress!.progress = theProgress
      } else {
        let newAudioPlayProgress = NSEntityDescription.insertNewObject(forEntityName: progressEntityName, into: context) as! AudioPlayProgress
        newAudioPlayProgress.audioID = id
        newAudioPlayProgress.progress = theProgress
      }
      try context.save()
      
//      loggingPrint("[\(name ?? "--")] \(getPlayProgress())")
    } catch let error {
      loggingPrint(error)
    }
  }
  
  func getPlayProgress() -> Float {
    let request = NSFetchRequest<AudioPlayProgress>()
    request.entity = NSEntityDescription.entity(forEntityName: progressEntityName, in: context)
    request.predicate = NSPredicate(format: "audioID = %@", "\(id)")
    do {
      let audioPlayProgress = try context.fetch(request).first
      if audioPlayProgress != nil {
        return audioPlayProgress!.progress
      } else {
        return 0
      }
    } catch let error {
      loggingPrint(error)
      return 0
    }
  }
  
  func removeCachedfile() {
    if let url = localURL {
      do {
        try FileManager.default.removeItem(atPath: url.path)
      } catch let error {
        loggingPrint("[\(name ?? "--")] delete cache file error. \(error)")
      }
    }
  }
}
